package com.sali.rule;

import cn.hutool.core.date.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.internet.MailDateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;


public class DataToTimestampRule implements Rule {
    private static final Logger logger = LoggerFactory.getLogger(DataToTimestampRule.class);
    private static final MailDateFormat mailDateFormat = new MailDateFormat();
    private static final String PLUS = "+";
    private static Rule rule;

    static {
        rule = new DataToTimestampRule();
    }

    @Override
    public Object invoke(Object value) {
        if (value instanceof Date) {
            return ((Date) value).getTime();
        } else if (value instanceof String) {
            return formatTime3((String) value);
        } else {
            return System.currentTimeMillis();
        }
    }

    /**
     * 格式化时间
     *
     * @param value
     * @return
     */
    @Deprecated
    public long formatTime(String value) {
        try {
            //SimpleDateFormat 在多线程下存在转换成时间戳错误
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE,dd MMM yy HH:mm:ss", Locale.ENGLISH);
            long time = simpleDateFormat.parse((String) value).getTime();
            if (time < 0) {
                logger.warn("报文日期格式不正确输出时间为：{},原始数据为：{}", time, value);
                time = System.currentTimeMillis();
            }
            /**
             * @auth zww
             * @date 2021-07-25
             * @desc 增加时区相关代码
             */
            if (value.contains(PLUS)) {
                Calendar calendar = Calendar.getInstance();
                TimeZone timeZone = calendar.getTimeZone();
                String[] split = ((String) value).split("\\+");
                int zone = Integer.parseInt(split[1].substring(0, 2));
                time = time - (zone * 3600 * 1000) + timeZone.getRawOffset();
            }
            return time;
        } catch (NumberFormatException | ParseException | ArrayIndexOutOfBoundsException | ClassCastException e) {
            return System.currentTimeMillis();
        }
    }

    /**
     * @param value
     * @return
     */
    @Deprecated
    public Long formatTime2(String value) {
        try {
            SimpleDateFormat simpleDateFormat = null;
            if (value.contains(",")) {
                //SimpleDateFormat 在多线程下存在转换成时间戳错误
                simpleDateFormat = new SimpleDateFormat("EEE,dd MMM yy HH:mm:ss", Locale.ENGLISH);
            } else {
                //SimpleDateFormat 在多线程下存在转换成时间戳错误
                simpleDateFormat = new SimpleDateFormat("dd MMM yy HH:mm:ss", Locale.ENGLISH);
            }

            long time = simpleDateFormat.parse(value).getTime();
            if (time < 0) {
                logger.warn("报文日期格式不正确输出时间为：{},原始数据为：{}", time, value);
                return null;
            }

            /**
             * @desc 增加时区相关代码
             */
            if (value.contains(PLUS)) {
                Calendar calendar = Calendar.getInstance();
                TimeZone timeZone = calendar.getTimeZone();
                String[] split = value.split("\\+");
                int zone = Integer.parseInt(split[1].substring(0, 2));
                time = (time - (zone * 3600 * 1000)) + timeZone.getRawOffset();
            }
            return time;
        } catch (NumberFormatException | ParseException | ArrayIndexOutOfBoundsException | ClassCastException e) {
            return null;
        }
    }

    /**
     * 转换时间
     *
     * @param value
     * @return
     */
    public Long formatTime3(String value) {
        Date date = null;
        try {
            synchronized (mailDateFormat) {
                date = mailDateFormat.parse(value);
            }
        } catch (ParseException e) {
        }
        return date == null ? null : date.getTime();
    }

    /**
     * 获取实例方法
     *
     * @return
     */
    public static Rule getInstance() {
        return rule;
    }

    public static void main(String[] args) throws ParseException, InterruptedException {
        Rule instance = DataToTimestampRule.getInstance();

        long time1 = (long) instance.invoke("Fri, 13 Aug 2021 15:06:29 +0000");
        long time2 = (long) instance.invoke("22 Aug 2021 11:06:56 +0200");
        long time3 = (long) instance.invoke("13 Aug 2021 14:38:12 +0000");

        Set<Long> sets = new HashSet<>();

        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(() -> {
                for (int j = 0; j < 100000; j++) {
                    long invoke = (long) instance.invoke("22 Aug 2021 11:06:56 +0200");
                    synchronized (sets) {
                        sets.add(invoke);
                    }
                    System.out.println("当前线程:" + Thread.currentThread().getName() + " value is " + DateUtil.date(invoke).toString());
                    try {
                        TimeUnit.MILLISECONDS.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        Thread.currentThread().interrupt();
                    }
                }
            });

            threads[i].setName("thread-" + i);
            threads[i].start();
        }


        for (int i = 0; i < 10; i++) {
            threads[i].join();
        }


        System.out.println("set size is " + sets.size());
    }
}
